<?
/////////////////////////////////////////////////////////////////////////////////////////
// Clase para Manejar DBF
/////////////////////////////////////////////////////////////////////////////////////////

/// class DatabaseDBF
class DatabaseDBF {
	// Propiedades de la Conexion
	var $idCon;
	var $cDirectorio;
	var $cArchivo;

	// Propiedades para el manejo de resultsets
	var $nTotalRegistros;
	var $nTotalCampos;
	var $nCurrentRecord;
	var $aFields;
	var $aArchivos;
	var $aFormat;

	function status() {
		return 'Directorio: ' . $this->cDirectorio . ' Archivo: ' . $this->cArchivo  . ' ConId: ' . $this->idCon ;
	}

	function totalFilas() {

	}

	function DatabaseDBF( $cDirectorio = "", $cArchivo = ""){
		$this->idCon = 0;

		if ( $cDirectorio ) {
		    $this->setDirectorio( $cDirectorio );
			if ( !$this->connect() )
				return false;
		}

		if ( $cArchivo != "" ) {
			if ( ! ($this->query($cArchivo) ) )
				return false;
		}
		return true;
	}
	
	function setDirectorio( $cDirectorio ) {
	    
		if (file_exists($cDirectorio) ) {
			if ( substr($cDirectorio, -1) != '/' ) 
			{
				$cDirectorio .= '/';
			}			
            $this->cDirectorio = $cDirectorio;
            return true;
		} else {
	        addMessage( "No existe el directorio: $cDirectorio" );
			return false;
		}		
	}

	function connect() {	    		
		if ( $this->cDirectorio == '' ) {
		    $this->setDirectorio( '.' );
		}
		

		// Arma un Array con los Archivos del Directorio
		$fdDirectorio = opendir($this->cDirectorio);
		unset($this->aArchivos);
		while ( $cArchivoNuevo = readdir($fdDirectorio)) {
			$this->aArchivos[] = $cArchivoNuevo;
		}
		closedir($fdDirectorio);
					
		return true;
	}

	function count() {
		return dbase_numrecords( $this->idCon );
	}

	function countFields() {
		return dbase_numfields( $this->idCon );
	}

    function insertArray( $cArchivo, $cCampo, $cValor ) {
        // Si no esta abierto => intenta abrirlo
        if ( $this->cArchivo != $cArchivo ) {
            if ( $this->query($cArchivo, 2) == false )
                return false;
        }

        // Arma el Array con Valores en el Orden de la Tabla
        for( $nCampo = 0; $nCampo < count($this->aFormat) ; $nCampo++ ) {
            for ( $nContador = 0; $nContador < count($cCampo) ; $nContador++ ) {
                if ( strtoupper( $this->aFormat[$nCampo] ) == strtoupper ( $cCampo[$nContador] ) ) {
                    $aValores[$nCampo] = $cValor[$nContador];
                    break;
                }
            }
        }
        if ( is_array(  $aValores ) ) {
            $bRet = dbase_add_record ( $this->idCon, $aValores ) ;
        } else {
            $bRet = FALSE;
        }
	}

    function insert( $cArchivo, $cCampo, $cValor ) {
        // Si no esta abierto => intenta abrirlo
        if ( $this->cArchivo != $cArchivo ) {
            if ( $this->query($cArchivo, 2) == false )
                return false;
        }

        // Arma el Array con Valores en el Orden de la Tabla
        for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  ) {
            for( $nCampo = 0; $nCampo < count($this->aFormat) ; $nCampo++ ) {
                if ( $this->aFormat[$nCampo] == func_get_arg($nContador) ) {
                    $aValores[$nCampo] = func_get_arg($nContador + 1);
                    break;
                }
            }
        }
        
        if ( is_array(  $aValores ) ) {
            $bRet = dbase_add_record ( $this->idCon, $aValores ) ;
        } else {
            $bRet = FALSE;
        }

        return $bRet;
	}


	function delete( $cArchivo, $cClave, $cValor ) {
        // Si no esta abierto => intenta abrirlo
        if ( $this->cArchivo != $cArchivo ) {
            if ( $this->query($cArchivo, 2) == false )
                return false;
        }

        // Por cada Registro Chequea la Condicion
        $nRegistro = 0;
        while ( $this->moveNext() ) {
            $bBorrar = true;
            if ( $cClave && $cValor ) {
                for ( $nContador = 1; $bBorrar == true && $nContador < func_num_args();  $nContador+=2  ) {
                    $cCampo = func_get_arg($nContador);
                    $cValor = func_get_arg($nContador + 1);
    
                    if ( $this->aFields[$cCampo] != $cValor ) {
                        $bBorrar = false;
                    }
                }
            }

            // Borra el Registro
            if ( $bBorrar == true ) {
                dbase_delete_record ( $this->idCon, $nRegistro );
            }

            $nRegistro++;
        }
	}

	function pack( $cArchivo ) {
        // Si no esta abierto => intenta abrirlo
        if ( $this->cArchivo != $cArchivo ) {
            if ( $this->query($cArchivo, 2) == false )
                return false;
        }

	    dbase_pack ($this->idCon);
	}


	// $nModo: 0)Read Only      1)Write Only     2)Read & Write
	function query( $cSql, $nModo = 0 ){
	    if ( $this->idCon ) {
	        dbase_close ( $this->idCon ) ;
	    }
	    
	    // Verifica si viene SELECT ... o ARCHIVO.DBF
	    $cSql = trim( $cSql );
	    $nPosCampos = 7;
	    if ( substr($cSql, 0, $nPosCampos) == 'SELECT ' ) {
            // Obtiene los punteros de la Instruccion
            $cSqlUpper = strtoupper($cSql);
    		$nPosFrom  = strpos($cSqlUpper, " FROM " );
    		$nPosAlias = strpos($cSqlUpper, " AS ", $nPosFrom );
    		$nPosWhere = strpos($cSqlUpper, " WHERE ", $nPosFrom );

	        // 1. Obtiene un Array con los Campos
    		if ( $nPosFrom === false ) {
    		    addMessage( "No se encontro FROM en el SQL");
    		    return false;
    		}
	        $cCampos = substr($cSql, $nPosCampos, $nPosFrom - $nPosCampos );

	        $aCampos = explode( ",", $cCampos );

	        // 2. Obtiene el Nombre del Archivo
	        $nPosHasta = ( $nPosAlias === false  ) ? $nPosWhere: $nPosAlias;
	        if ( $nPosHasta === false  ) {
	            $cArchivo = substr($cSql, $nPosFrom + 6 );
	        } else {
	            $cArchivo = substr($cSql, $nPosFrom + 6 , $nPosHasta - $nPosFrom - 6 );
	        }
	        // 3. Obtiene la Where Condition
	        if ( $nPosWhere ) {
	            $this->cWhere = substr($cSql, $nPosWhere  + 7 );
	        }
	    } else {
	        $cArchivo = $cSql;
	    }


		$this->cArchivo = $cArchivo;

		// Si el Archivo no Existe busca uno con el mismo nombre pero no case sensitive
		if ( file_exists ( $this->cDirectorio . $this->cArchivo ) == FALSE ) {
			foreach ( $this->aArchivos as $cArchivoNuevo ) {
				if ( strtoupper($cArchivoNuevo) == strtoupper($cArchivo) ) {
					$this->cArchivo = $cArchivoNuevo;
				}
			}
		}

		// Abre el Archivo
		
		$this->idCon = dbase_open ( $this->cDirectorio . $this->cArchivo, $nModo );
		if ( $this->idCon === false ) {
			return false;
		}

		// Inicializa Variables
		$this->nTotalRegistros = $this->count();
		$this->nCurrentRecord = 0;
		unset($this->aFormat);

        // Inicializa aFormat con los Nombres de los campos
        if ( $cCampos == '' || $cCampos == '*' ) {
    		$this->nTotalCampos  = $this->countFields();
    		if ( $this->moveTo(0) == false && $nModo == 1 )  {
    		  return false;
            }

    		$aFields = dbase_get_record_with_names( $this->idCon, 0  );    		
    		
    		foreach ( $aFields as $cCampo => $cValor ) {
    		    $this->aFormat[] = $cCampo;
    		}
        } else {
            $this->nTotalCampos  = count($aCampos);
    		foreach ( $aCampos as $cCampo ) {
    		    $this->aFormat[] = $cCampo;
    		}
    	}

		return true;
	}

	function getMatrix($cArchivo) {
		if ( $this->query($cArchivo) === false ) {
			return false;
		}
		for ( $nRegistro = 0; $nRegistro <= $this->nTotalRegistros; $nRegistro++ ) {
			$aRecNombres[$nRegistro] = dbase_get_record_with_names($this->idCon, $nRegistro);
		}
		return $aRecNombres;
	}

	function __goTo( $nRow ) {
	    $this->moveTo( $nRow  );
	}

	function moveTo( $nRow ) {
		if ( $this->idCon == 0 )
			return false;

		if ($nRow < $this->nTotalRegistros) {
			$this->nCurrentRecord = $nRow;
			$this->aFields = dbase_get_record_with_names($this->idCon, $this->nCurrentRecord);
		} else {
			return false;
		}
		return !empty($this->aFields);
	}

	function moveNext() {
		if ( $this->idCon == 0 )
			return false;
		if ($this->nCurrentRecord < $this->nTotalRegistros) {
		    $this->nCurrentRecord++;
			$this->aFields = dbase_get_record_with_names($this->idCon, $this->nCurrentRecord);
		} else {
			return false;
		}
		return !empty($this->aFields);
	}
}

?>
